/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package queenb.net.util;

import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.*;
import org.hibernate.cfg.*;

/**
 *
 * @author HP
 */
public class HibernateUtil {

    private static final Log log = LogFactory.getLog(HibernateUtil.class);
    /**
     * Read the configuration, will share across threads*
     */
    private static SessionFactory sessionFactory;
    private static SessionFactory sessionFactoryEn;
    private static boolean flag = true;
    /**
     * the per thread session *
     */
    private static final ThreadLocal<Session> currentSession = new ThreadLocal<Session>();
    /**
     * The constants for describing the ownerships *
     */
    private static final Owner trueOwner = new Owner(true);
    private static final Owner fakeOwner = new Owner(false);
    /**
     * set this to false to test with JUnit *
     */
    private static final boolean isLife = true;

    /**
     * get the hibernate session and set it on the thread local. Returns
     * trueOwner if it actually opens a session
     */
    public static Object createSession() throws Exception {
        Session session = (Session) currentSession.get();
        //System.out.println(session);
        if (session == null) {
            //System.out.println("No Session Found - Create and give the identity");

            session = getSessionFactory().openSession();


            currentSession.set(session);
            return trueOwner;
        }
        //System.out.println("Session Found - Give a Fake identity");
        return fakeOwner;
    }

    /**
     * The method for closing a session. The close and flush will be executed
     * only if the session is actually created by this owner.
     */
    public static void closeSession(Object ownership) throws Exception {
        try {
            if (((Owner) ownership).identity) {
                //System.out.println("Identity is accepted. Now closing the session");
                Session session = (Session) currentSession.get();
                session.flush();
                session.close();
                currentSession.set(null);
            } else {
                System.out.println("Identity is rejected. Ignoring the request");
            }
        } catch (Exception ex) {
        }


    }

    /**
     * returns the current session
     */
    public static Session getSession() throws HibernateException {
        return (Session) currentSession.get();
    }

    /**
     * Creating a session factory , if not already loaded
     */
    private static SessionFactory getSessionFactory() {
        try {
            if (sessionFactory == null) {

                sessionFactory = new Configuration().configure().buildSessionFactory();

            }
            return sessionFactory;
        } catch (HibernateException e) {
            log.error("getSessionFactory", e);
            return null;
        } catch (Exception err) {
            log.error("getSessionFactory", err);
            return null;
        }

    }

    /**
     * @return the sessionFactoryEn
     */
    public static SessionFactory getSessionFactoryEn() {
        try {
            if (sessionFactoryEn == null) {

                sessionFactoryEn = new Configuration().configure("hibernate1.cfg.xml").buildSessionFactory();

            }
            return sessionFactoryEn;
        } catch (HibernateException e) {
            log.error("getSessionFactory", e);
            return null;
        } catch (Exception err) {
            log.error("getSessionFactory", err);
            return null;
        }

    }

    /**
     * @return the flag
     */
    public static boolean isFlag() {
        return flag;
    }

    /**
     * @param aFlag the flag to set
     */
    public static void setFlag(boolean aFlag) {
        flag = aFlag;
    }

    /**
     * @param aSessionFactoryEn the sessionFactoryEn to set
     */
    public static void setSessionFactoryEn(SessionFactory aSessionFactoryEn) {
        sessionFactoryEn = aSessionFactoryEn;
    }

    /**
     * Internal class , for handling the identity. Hidden for the developers
     */
    private static class Owner {

        public Owner(boolean identity) {
            this.identity = identity;
        }
        boolean identity = false;
    }
}
